#include <jni.h>
#include <android/log.h>
#include <cstddef>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#define LOG_TAG "operator"
#define LOGD(str) __android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, str);

char* jstringTostring(JNIEnv* env, jstring jstr);
jstring stoJstring(JNIEnv* env, const char* pat);

jint native_start(JNIEnv *env, jobject obj) {
	LOGD("----------start----------");
	return 0;
}

jboolean native_writeDataFromDevice(JNIEnv *env, jobject obj, jstring dev,
		jstring data) {
	LOGD("----------native_writeDataFromDevice----------");
	FILE* fp;
	int flag = 0;
	const char *filePath = jstringTostring(env, dev);
	if ((fp = fopen(filePath, "w")) != NULL) {
		fprintf(fp, "%s", jstringTostring(env, data));
		flag = 1;
	} else {
		flag = 0;
	}
	fclose(fp);
	return flag;
}

jstring native_readDataFormDeivce(JNIEnv *env, jobject obj, jstring dev) {
	LOGD("----------native_readDataFormDeivce----------");
	FILE *fp;
	char status[50];
	const char *filePath = jstringTostring(env, dev);
	if ((fp = fopen(filePath, "r")) == NULL) {
		return env->NewStringUTF((char*) "");;
	} else {
		int flag = fscanf(fp, "%s", status);
	}
	fclose(fp);
	char* result;
	result =  (char*)malloc(50);
	strcpy(result,status);

	jstring jstrBuf = env->NewStringUTF(result);
	return jstrBuf;
}

char* jstringTostring(JNIEnv* env, jstring jstr) {
	char* rtn = NULL;
	jclass clsstring = env->FindClass("java/lang/String");
	jstring strencode = env->NewStringUTF("utf-8");
	jmethodID mid = env->GetMethodID(clsstring, "getBytes",
			"(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
	jsize alen = env->GetArrayLength(barr);
	jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
	if (alen > 0) {
		rtn = (char*) malloc(alen + 1);

		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	env->ReleaseByteArrayElements(barr, ba, 0);
	return rtn;
}

jstring stoJstring(JNIEnv* env, const char* pat) {
	jclass strClass = env->FindClass("Ljava/lang/String;");
	jmethodID ctorID = env->GetMethodID(strClass, "<init>",
			"([BLjava/lang/String;)V");
	jbyteArray bytes = env->NewByteArray(strlen(pat));
	env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*) pat);
	jstring encoding = env->NewStringUTF("utf-8");
	return (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
}

static JNINativeMethod gMethods[] = { { "native_start", "()I",
		(void*) native_start }, { "native_writeDataFromDevice",
		"(Ljava/lang/String;Ljava/lang/String;)Z",
		(void*) native_writeDataFromDevice }, { "native_readDataFormDeivce",
		"(Ljava/lang/String;)Ljava/lang/String;",
		(void*) native_readDataFormDeivce }, };

//Class path name for Register
static const char *classPathName = "com/cxb/utils/OperateSysDevicesUtils";

/*
 * Ϊĳһ����ע�᱾�ط���
 */
static int registerNativeMethods(JNIEnv* env, const char* className,
		JNINativeMethod* gMethods, int numMethods) {
	jclass clazz;
	clazz = env->FindClass(className);
	if (clazz == NULL) {
		return JNI_FALSE;
	}
	if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
		return JNI_FALSE;
	}

	return JNI_TRUE;
}

/*
 * Ϊ������ע�᱾�ط���
 */
static int registerNatives(JNIEnv* env) {
	return registerNativeMethods(env, classPathName, gMethods,
			sizeof(gMethods) / sizeof(gMethods[0]));
}
/*
 * System.loadLibrary("lib")ʱ����
 * ���ɹ�����JNI�汾, ʧ�ܷ���-1
 */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
	JNIEnv* env = NULL;
	jint result = -1;

	if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
		return -1;
	}
	assert(env != NULL);

	if (!registerNatives(env)) { //ע��
		return -1;
	}
	//�ɹ�
	result = JNI_VERSION_1_4;

	return result;
}
